package co.com.javeriana.aes.patrones.saiii.cliente.canales;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectInputStream;
import java.io.ObjectOutput;
import java.io.ObjectOutputStream;
import co.com.javeriana.aes.patrones.saiii.cliente.topics.Clientes;
import co.com.javeriana.aes.patrones.saiii.cliente.topics.Topicos;
import co.com.javeriana.aes.patrones.saiii.dto.Cliente;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.QueueingConsumer;

public  class LeerOperaciones {

	private static final  String host = "25.124.75.91";
	
	
	public static void main(String[] argv) throws Exception {

		Cliente c = new Cliente();
		c.setName("");
		c.setRecibirNotificaiones(true);
		c.setRespuesta("res");
		c.setTiempoRespuesta("");
		c.setTipo("A");

		//publicar(Clientes.CLIENTE_1, Topicos.CREAR_ORDEN, c);
		leer(Clientes.CLIENTE_1, Topicos.CREAR_ORDEN);

	}

	public static void publicar(Clientes canal, Topicos topicos, Object objeto)
			throws Exception {

		ConnectionFactory factory = new ConnectionFactory();
		factory.setHost(host);
		factory.setUsername("admin");
		factory.setPassword("123");
		Connection connection = factory.newConnection();
		Channel channel = connection.createChannel();

		channel.exchangeDeclare(canal.name(), "topic", true);
		// channel.exchangeDeclare("CANAL", "TOPICO");

		channel.basicPublish(canal.name(), "topic", null,
		serializar(objeto));
		//channel.basicPublish(canal.name(), topicos.name(), null,"test".getBytes());

		connection.close();
	}

	public static void leer(Clientes canal, Topicos topicos) throws Exception {

		ConnectionFactory factory = new ConnectionFactory();
		factory.setHost(host);
		factory.setUsername("admin");
		factory.setPassword("123");
		Connection connection = factory.newConnection();
		Channel channel = connection.createChannel();

		channel.exchangeDeclare(canal.name(), "topic");
		String queueName = channel.queueDeclare().getQueue();

		/*
		 * if (argv.length < 1){
		 * System.err.println("Usage: ReceiveLogsTopic [binding_key]...");
		 * System.exit(1); }
		 */

		// for(String bindingKey : argv){
		channel.queueBind(queueName, canal.name(), topicos.name());
		// }

		System.out.println(" [*] Waiting for messages. To exit press CTRL+C");

		QueueingConsumer consumer = new QueueingConsumer(channel);
		channel.basicConsume(queueName, true, consumer);

		while (true) {

			QueueingConsumer.Delivery delivery = consumer.nextDelivery();
			Object o = desSerializar (delivery.getBody());
			//String routingKey = delivery.getEnvelope().getRoutingKey();
			//System.out.printf("", message, routingKey);
		}

	}

	@SuppressWarnings("unused")
	private static byte[] serializar(Object objeto) {

		ByteArrayOutputStream bos = new ByteArrayOutputStream();
		ObjectOutput out = null;
		byte[] yourBytes = null;

		try {

			out = new ObjectOutputStream(bos);
			out.writeObject(objeto);
			yourBytes = bos.toByteArray();

		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {

			try {
				if (out != null) {
					out.close();
				}
			} catch (Exception ex) {
				// ignore close exception
			}
			try {
				bos.close();
			} catch (Exception ex) {
				// ignore close exception
			}
		}

		return yourBytes;
	}
	
	
	public static Object desSerializar(byte[] yourBytes) {

		ByteArrayInputStream bis = new ByteArrayInputStream(yourBytes);
		ObjectInput in = null;
		Object objeto = null;
		try {
			in = new ObjectInputStream(bis);
			objeto = in.readObject();

		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			try {
				bis.close();
			} catch (IOException ex) {
				// ignore close exception
			}
			try {
				if (in != null) {
					in.close();
				}
			} catch (IOException ex) {
				// ignore close exception
			}
		}
		return objeto;
	}

}
